/* #ifndef __SHM_HPP__
#define __SHM_HPP__
#include<iostream>
#include<string>
#include <sys/types.h>//ftok
#include <sys/ipc.h>//ftok
#include <sys/ipc.h>//shmget
#include <sys/shm.h>//shmget


using  namespace std;
const int gCreator=1;
const int gUer=2;
const string pathname="/home/zjw/lesson25";
const int g_id=0x21;
const int gshmsize=4096;
class shm
{
private:
   key_t getcommkey()  //获得key,是用户给系统用来唯一确定一块共享内存
   {
    key_t k=ftok(_pathname.c_str(),_id);//两个都是用户给的
    if(k<0)
    {

        perror("ftok");
    }
    return k;
   }

   int getshmhelper(key_t key,int size,int flag)
   {

   int shmid=shmget(key,size,flag);//创建共享内存的函数//key是用户给操作系统，方便其他进程找到对应的共享内存，size是共享内存的大小//flag是共享内存的权限
    //flag可以区分是创建共享内存的，还是找共享内存的
  if(shmid<0)
  {perror("shmid");}
  return shmid;//shmid<0说明共享内存申请失败，shmid是操作系统给用户的，方便用户对共享内存的操作，比如说删除共享内存

   }
public:
    shm(const string &pathname,int id,int who)
    :_pathname(pathname)
    ,_id(id)
    ,_who(who)
    {
     _key=getcommkey();//相当于初始化时创建端的key和找key的进程一样，因为ftok函数的两个参数都是全局的，返回的key是一样的
     if(_who==gCreator)getshmusecreate();
     else if(_who==gUer)getshmforusr();
        cout<<"shmid:"<<_shmid<<endl;
       cout<<"_key:"<<_key<<endl;
    }

    bool getshmusecreate()
    {
      if(_who==gCreator)
      {
              _shmid= getshmhelper(_key,gshmsize,IPC_CREAT|IPC_EXCL|0666);
              if(_shmid>=0)
                {cout<<"shm create done..."<<endl;
                return true;}
      }
      return false;

    
    }

    bool getshmforusr()
    {

    if(_who==gUer)
      {
       _shmid=getshmhelper(_key,gshmsize,IPC_CREAT|0666);
       if(_shmid>=0)
        { cout<<"shm get done..."<<endl;
         return true;
        }
         
      }
       return false;
    }
~shm()
{
if(_who==gCreator)
  {


   int res=shmctl(_shmid,IPC_RMID,nullptr);//第一个参数是对一个共享内存的标识，给用户，方便用户对共享内存进行操作，IPC_RMID对共享内存的删除
//第三个一个结构体的地址，保存共享内存的属性
  cout<<"shm remove done..."<<endl;
  }
  
}
private:
key_t _key;
int _shmid;
string _pathname;
int _id;
int _who;
}; */



////////////////////////////////////////////////////////////
#ifndef __SHM_HPP__
#define __SHM_HPP__
#include<iostream>
#include<string>
#include <unistd.h>
#include <sys/types.h>//ftok
#include <sys/ipc.h>//ftok
#include <sys/ipc.h>//shmget
#include <sys/shm.h>//shmget
using  namespace std;
const int gCreator=1;
const int gUer=2;
const string pathname="/home/zjw/lesson25";
const int g_id=0x21;
const int gshmsize=4096;
class shm
{
private:
   key_t getcommkey()  //获得key,是用户给系统用来唯一确定一块共享内存
   {
    key_t k=ftok(_pathname.c_str(),_id);//两个都是用户给的
    if(k<0)
    {

        perror("ftok");
    }
    return k;
   }

   int getshmhelper(key_t key,int size,int flag)
   {

   int shmid=shmget(key,size,flag);//创建共享内存的函数//key是用户给操作系统，方便其他进程找到对应的共享内存，size是共享内存的大小//flag是共享内存的权限
    //flag可以区分是创建共享内存的，还是找共享内存的
  if(shmid<0)
  {perror("shmid");}
  return shmid;//shmid<0说明共享内存申请失败，shmid是操作系统给用户的，方便用户对共享内存的操作，比如说删除共享内存

   }
   void* attachshm()
   {
    //if(_addrshm!=nullptr)
      // detachshm(_addrshm);
       void*shmaddr=shmat(_shmid,nullptr,0);
       if(shmaddr==nullptr)
       {
        perror("shmat");

       }
       cout<<"who:>"<<_who<<"< "<<"1是gCreator,2是gUer"<<"对应进程共享内存和地址空间链接"<<endl;
      
       return shmaddr;
   }
   void detachshm(void* shmaddr)
   {
    if(shmaddr==nullptr)
    return ;
    shmdt(shmaddr);//将共享内存段从调用进程的地址空间中分离。
    //cout<<"who:>"<<_who<<"< "<<"1是gCreator,2是gUer"<<"对应进程共享内存和地址空间断开链接"<<endl;

   }
public:
    shm(const string &pathname,int id,int who)
    :_pathname(pathname)
    ,_id(id)
    ,_who(who)
    {
     _key=getcommkey();//相当于初始化时创建端的key和找key的进程一样，因为ftok函数的两个参数都是全局的，返回的key是一样的
     if(_who==gCreator)getshmusecreate();
     else if(_who==gUer)getshmforusr();
     _addrshm=attachshm();
     
    
    }

    bool getshmusecreate()
    {
      if(_who==gCreator)
      {
              _shmid= getshmhelper(_key,gshmsize,IPC_CREAT|IPC_EXCL|0666);
              if(_shmid>=0)
                {cout<<"shm create done..."<<endl;
                return true;}
      }
      return false;

    
    }

    bool getshmforusr()
    {

    if(_who==gUer)
      {
       _shmid=getshmhelper(_key,gshmsize,IPC_CREAT|0666);
       if(_shmid>=0)
        { cout<<"shm get done..."<<endl;
         return true;
        }
         
      }
       return false;
    }
~shm()
{
if(_who==gCreator)
  {


   int res=shmctl(_shmid,IPC_RMID,nullptr);//第一个参数是对一个共享内存的标识，给用户，方便用户对共享内存进行操作，IPC_RMID对共享内存的删除
//第三个一个结构体的地址，保存共享内存的属性
  cout<<"shm remove done..."<<endl;
  }
  
}
void* addr()
{

return _addrshm;


}
private:
key_t _key;
int _shmid;
string _pathname;
int _id;
int _who;
void*_addrshm;
}; 

































#endif